package com.yinxing.framework.convert;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yinxing.framework.exception.ParameterException;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * Spring参数转换器(用于处理分页参数)
 * 负责把URL(?page=1&limit=20)后面的分页参数 封装为Page对象
 */
public class PageParamConvert implements HandlerMethodArgumentResolver {
	
	private static final String pageParameterName = "page";
	
	private static final String limitParameterName = "limit";

	private static final Class[] constructorParams = new Class[]{long.class, long.class};

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return Page.class == parameter.getParameterType();
	}

	@Override
	public Object resolveArgument(MethodParameter parameter,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
			WebDataBinderFactory binderFactory) throws Exception {

		HttpServletRequest request = (HttpServletRequest)webRequest.getNativeRequest();

		final Integer page = ServletRequestUtils.getIntParameter(request, pageParameterName);
		if(page == null) {
			throw new ParameterException("参数page(int)必须传递");
		}
		final Integer limit = ServletRequestUtils.getIntParameter(request, limitParameterName);
		if(limit == null) {
			throw new ParameterException("参数limit(int)必须传递");
		}

		//反射创建Page对象,相当于Page p = new Page(page, limit);
		Object instance = parameter.getParameterType().getDeclaredConstructor(constructorParams)
				.newInstance(new Object[]{page, limit});
		return instance;
	}
}
